home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
476-500
/
disk_497
/
nlcalc
/
source
/
csetup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
6KB
|
210 lines
/*
* CALC Provides a calculator that opens on the active screen when
* you press a specific key sequence. Otherwise, the program
* waits quitely in the background.
*
* Copyright 1989 by Davide P. Cervone.
* You may use this code, provided this copywrite notice is kept intact.
*/
#define INTUITION_PREFERENCES_H /* don't need 'em */
#include <intuition/intuitionbase.h>
#include <exec/interrupts.h>
#include <devices/input.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <proto/exec.h>
#include "cHandler.h"
#include "cSetup.h"
extern struct Process *FindTask();
#define GETSTARTUP(p) ((struct StartupMessage *)GetMsg(p))
#define ONE 1L
#define SIGBREAKF_ANY\
(SIGBREAKF_CTRL_C| SIGBREAKF_CTRL_D| SIGBREAKF_CTRL_E| SIGBREAKF_CTRL_F)
extern void myHandlerStub();
#ifndef SWINDOWS
extern void aCloseScreen();
extern void cCloseScreen();
long OldCloseScreen;
#endif
LONG CalcSMask; /* Signal for calc to open on active screen */
static LONG CalcSSignal; /* Signal number for CalcSMask */
#ifndef SWINDOWS
LONG CalcCMask; /* Signal for screen close */
static LONG CalcCSignal; /* Signal number for CalcCMask */
#endif
struct Task *CalcTask; /* Pointer to Calc task */
static struct Task *ParentTask; /* Pointer to parent task */
extern UWORD KeyCode; /* KeyCode to activate Calc */
extern UWORD Qualifiers; /* and required qualifiers */
static struct Interrupt Calc_Interrupt = /* the Interrupt needed to add a */
{ /* handler to the input chain */
{NULL, NULL, 0, 51, NULL}, /* ln_Pri = 51 (before Intuition) */
NULL,
&myHandlerStub /* the handler to add */
};
static struct HandlerData cHandlerData =
{
{ /* the MsgPort is pre-setup */
{NULL,NULL, NT_MSGPORT, 0, PORTNAME}, /* to include the name and */
PA_IGNORE, 0, NULL, /* type so that it can just */
{NULL,NULL,NULL, 0,0} /* be added to the port list */
}, /* so it can be found later */
MAJVERS,MINVERS, MINLOADVER, /* the handler versio numbers */
NULL, /* the handler code segment */
&IntuitionBase, /* pointer to IntuitionBase and */
&GfxBase, /* GfxBase (set up by loader) */
&Calc_Interrupt, /* the interrupt used by Input.Device */
&ParentTask, /* so we know who to signal later */
&KeyCode, /* the KeyCode to acticate calc */
&Qualifiers, /* and required qualifiers */
#ifndef SWINDOWS
&aCloseScreen, /* ASM CloseScreen stub */
&OldCloseScreen, /* result of SetFunction */
#else
NULL,NULL
#endif
};
/*
* cExit()
*
* End CalcTask from running. Forbid() so that we are not unloaded until
* after we're done exiting. Signal the parent that we are done running,
* and exit.
*/
void cExit()
{
Forbid();
if (ParentTask) Signal(ParentTask,ENDSIGNAL);
Exit(0);
}
/*
* GetSignal()
*
* Allocate a signal (error if none available) and set the mask to
* the proper value.
*/
#define DEFAULTSIGNAL 20
void GetSignal(theSignal,theMask)
LONG *theSignal, *theMask;
{
LONG signal;
if ((signal = AllocSignal(-ONE)) == -ONE) signal = DEFAULTSIGNAL;
*theSignal = signal;
*theMask = (ONE << signal);
}
/*
* WaitForStartup()
*
* Find our task pointer and wait for a startup message passed buy the loader.
* (This structure is non-standard and is defined in cSetup.h). Check that
* we have not been signaled to end (in case the user executed the handler
* as a command, for example). Otherwise, once we have received the
* startup message, get the parent task pointer from the message, and
* check the loader version number. If OK, then set the HandlerData so
* the loader can do its thing. Finally, reply to the message to inform
* the loader that everything is ready for it.
*/
static void WaitForStartup()
{
struct Process *cTask = FindTask(NULL);
struct MsgPort *cPort = &cTask->pr_MsgPort;
struct StartupMessage *sMessage = NULL;
ULONG Mask = (ONE << cPort->mp_SigBit);
ULONG signals;
CalcTask = (struct Task *)cTask;
while (sMessage == NULL)
{
signals = Wait(Mask|ENDSIGNAL);
if (signals & ENDSIGNAL) cExit();
sMessage = GETSTARTUP(cPort);
}
ParentTask = sMessage->sm_ParentTask;
if (sMessage->sm_LoadVers < MINLOADVER)
sMessage->sm_HandlerData = NULL;
else
sMessage->sm_HandlerData = &cHandlerData;
ReplyMsg(sMessage);
}
/*
* InitCalc()
*
* Clear any pending signals, and wait for the startup message from the
* loader. Then wait for the loader to signal us that it is finished
* setting things up for us. If it signaled an END, then exit, otherwise
* allocate the signals that we will need
*/
void InitCalc()
{
ULONG signals;
SetSignal(0L,SIGBREAKF_ANY);
WaitForStartup();
signals = Wait(STARTSIGNAL | ENDSIGNAL);
if (signals & ENDSIGNAL) cExit();
GetSignal(&CalcSSignal,&CalcSMask);
#ifndef SWINDOWS
GetSignal(&CalcCSignal,&CalcCMask);
#endif
}
/*
* ConfirmExit()
*
* Called when the loader tries to unload the handler. First we signal
* the loader that everything is ready for it to try to deinstall us.
* Then we wait for it to signal that everything has be removed properly.
* If it signals us with ENDSIGNAL we can safely end (it has been able to
* remove everything). Otherwise, we must continue to run.
*/
int ConfirmExit()
{
ULONG signals;
int NotDone = TRUE;
if (ParentTask)
{
Signal(ParentTask,ENDSIGNAL);
signals = Wait(ENDSIGNAL | STARTSIGNAL);
if (signals & ENDSIGNAL) NotDone = FALSE;
}
return(NotDone);
}